<template>
  <div id="chat-app" class="github-theme">
    <div class="chat-container">
     
      <header class="header">
        <h1>DeepSeek AI 对话</h1>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
      </header>
      <div class="messages" ref="messagesContainer">
        <div v-for="(msg, index) in messages" :key="index" class="message">
          <template v-if="!msg.isUser">
            <div class="ai-container">
              <div class="avatar">
                <img src="@/assets/logo.png" alt="DeepSeek AI" class="avatar-img"/>
              </div>
              <div class="content">
                <div v-if="msg.thinking" class="thinking">
                  <div class="thinking-header">
                    思考过程（用时: {{ (msg.thinkingTime / 1000).toFixed(1) }}秒）
                  </div>
                  <blockquote v-html="formatContent(msg.thinking)"></blockquote>
                </div>
                <p class="answer" v-html="formatContent(msg.answer)"></p>
              </div>
            </div>
          </template>
          <div v-else class="user-container">
            <div class="content">
              <p class="user-msg">{{ msg.text }}</p>
            </div>
            <div class="avatar">我</div>
          </div>
        </div>
      </div>
      <form @submit.prevent="handleButton" class="input-form">
        <div class="input-container">
          <input v-model="inputText" type="text" placeholder="给AI发送消息" :disabled="isStreaming"/>
          <button type="submit" :class="{ cancel: isStreaming }">
            {{ isStreaming ? '■' : '发送' }}
          </button>
        </div>
      </form>
    </div>
  </div>
</template>

<script>
import OpenAI from "openai";
import { marked } from 'marked';

const client = new OpenAI({
  baseURL: "https://ai.gitee.com/v1",
  apiKey: "U3D04O0URUQZOTPFID2AROKMZFTUCQQKZHFNO1C1",
  defaultHeaders: { "X-Failover-Enabled": "true", "X-Package": "1910" },
  dangerouslyAllowBrowser: true
});

export default {
  name: 'App',
  data() {
    return {
      messages: [],
      inputText: '我想学习钢琴，你能给些学习钢琴的入门建议吗？',
      isStreaming: false,   // 表示 AI 回答是否正在进行
      cancelRequested: false  // 终止标志
    }
  },
  methods: {
    // 统一处理按钮点击，根据状态发送消息或终止回答
    handleButton() {
      if (this.isStreaming) {
        this.handleCancel();
      } else {
        this.handleSend();
      }
    },
    // 终止 AI 回答，将 cancelRequested 标志置为 true
    handleCancel() {
      this.cancelRequested = true;
      // 可额外提示用户已终止
    },
    
    // 修改格式化内容的方法，添加 markdown 支持
    formatContent(text) {
      if (!text) return ''
      const htmlContent = marked(text)
      return htmlContent
    },
    
    // 添加滚动到底部的方法
    scrollToBottom() {
      setTimeout(() => {
        const container = this.$refs.messagesContainer
        if (container) {
          container.scrollTop = container.scrollHeight
        }
      }, 0)
    },
    
    async handleSend() {
      const userMessage = this.inputText.trim()
      if (!userMessage) return

      // 重置取消状态并设为流式处理中
      this.cancelRequested = false;
      this.isStreaming = true;

      // 添加用户消息
      this.messages.push({ text: userMessage, isUser: true })
      this.inputText = ''

      try {
        const startTime = Date.now()
        let thinkingEndTime = 0
        let isThinking = true
        let fullContent = ''
        let currentThinking = ''
        let currentAnswer = ''
        
        // 添加一个 AI 消息占位
        const aiMessageIndex = this.messages.length
        this.messages.push({ 
          text: '', 
          thinking: '', 
          answer: '', 
          thinkingTime: 0,
          isUser: false 
        })

        // 调用 DeepSeek API
        const response = await client.chat.completions.create({
          model: "DeepSeek-R1-Distill-Qwen-32B",
          stream: true,
          max_tokens: 1024,
          temperature: 0.6,
          top_p: 0.7,
          top_k: 50,
          frequency_penalty: 0,
          messages: [
            {
              role: "system",
              content: "你是一个超级强大的人工智能助手，可以根据用户的问题快速思考并给出回答。"
            },
            {
              role: "user",
              content: userMessage
            }
          ],
        });

        // 处理流式响应
        for await (const chunk of response) {
          // 检查是否请求终止
          if (this.cancelRequested) {
            break;
          }

          const content = chunk.choices[0]?.delta?.content || ''
          fullContent += content
          
          if (isThinking && content.includes('</think>')) {
            isThinking = false
            thinkingEndTime = Date.now() - startTime
          }
          
          const thinkMatch = fullContent.match(/<think>(.*?)<\/think>/s)
          if (thinkMatch) {
            currentThinking = thinkMatch[1].trim()
            currentAnswer = fullContent.replace(/<think>.*?<\/think>/s, '').trim()
          } else {
            currentAnswer = fullContent.trim()
          }
          
          this.messages[aiMessageIndex] = {
            thinking: currentThinking,
            answer: currentAnswer,
            thinkingTime: thinkingEndTime || (isThinking ? Date.now() - startTime : 0),
            isUser: false
          }
          
          this.scrollToBottom()
        }
      } catch (error) {
        console.error(error)
        this.messages.push({ text: '调用 AI 对话服务失败。', isUser: false })
      }
      // 无论正常结束或取消，都重置流式状态
      this.isStreaming = false;
    }
  },
  watch: {
    messages: {
      deep: true,
      handler() {
        this.scrollToBottom()
      }
    }
  }
}
</script>

<style>
/* 整体主题 */
.github-theme {
  background-color: #ffffff;
}

.chat-container {
  max-width: 1000px;
  /* height: 100%; */
  margin: 0 auto;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color: #333;
  position: relative;
  display: flex;
  flex-direction: column;
}

/* 头部样式 */
.header {
  padding: 20px;
  margin-bottom: 24px;
  text-align: center;
}

.header h1 {
  font-size: 24px;
  font-weight: 600;
  margin: 0;
  color: #333;
}

/* 消息容器 */
.messages {
  flex: 1;
  padding: 20px; /* 右边距移除，让滚动条贴近边缘 */
  background-color: #ffffff;
  overflow-y: auto;
  margin-bottom: 80px; /* 为底部输入框留出空间 */
}

/* 消息样式 */
.message {
  margin: 16px 0;
}

.ai-container, .user-container {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* 头像样式 */
.avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;  /* 修改这里，从4px改为50%使其呈现圆形 */
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 500;
}

.avatar-img {
  width: 80%;
  height: 80%;
  object-fit: cover;
  border-radius: 50%;
  padding: 5px; /* 在图片周围添加一些内边距 */
}

.ai-container .avatar {
  background-color: transparent;
  border: 0.5px solid #ccd0daea; /* 添加灰色边框 */
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1); /* 添加淡蓝色阴影效果 */
  overflow: hidden; /* 确保图片不会超出圆形边框 */
  transition: all 0.3s ease;
}

.ai-container .avatar:hover {
  transform: scale(1.05);
  border-color: #1d4ed8;
}

.user-container .avatar {
  background-color: #2563eb;
}

/* 内容样式 */
.content {
  flex: 1;
  max-width: 90%;
}

.thinking {
  padding: 12px 16px;
  margin-bottom: 12px;
  border-radius: 4px;
}

.thinking-header {
  color: #666;
  font-size: 13px;
  margin-bottom: 8px;
}

.thinking blockquote {
  margin: 0;
  padding: 12px 16px;
  border-left: 4px solid #ddd;
  background-color: #f9fafb;
  color: #666;
  font-size: 14px;
  line-height: 1.5;
}

.answer, .user-msg {
  margin: 0;
  padding: 12px 16px;
  border-radius: 12px;
  line-height: 1.5;
  font-size: 14px;
}

.answer {
  background-color: #f9fafb;
  color: #333;
}

.user-msg {
  background-color: #eef2ff;
  color: #2563eb;
}

/* 输入框样式 */
.input-form {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #fff;
  padding: 16px;
  border-top: 1px solid #eee;
  z-index: 10;
}

.input-container {
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  gap: 8px;
}

input {
  flex: 1;
  padding: 8px 12px;
  font-size: 14px;
  border: 1px solid #ddd;
  border-radius: 4px;
  outline: none;
}

input:focus {
  border-color: #2563eb;
}

/* 基础按钮样式 */
button {
  width: 64px;  /* 添加固定宽度 */
  height: 36px; /* 添加固定高度 */
  padding: 8px 16px;
  font-size: 14px;
  color: #ffffff;
  background-color: #2563eb;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  
  /* 添加flex布局使内容居中 */
  display: flex;
  align-items: center;
  justify-content: center;
}

button:hover {
  background-color: #1d4ed8;
}

/* 当 AI 正在回答时，发送按钮应用终止样式，只将文本改为黑色的■并居中 */
button.cancel {
  font-size: 28px;  /* 调整终止符号大小 */
  color: #0a0a0a;
  background-color: #ffffff;
  border: 2px solid #0a0a0a;
  line-height: 1;  /* 添加行高为1确保垂直居中 */
  padding: 0;      /* 移除内边距 */
  padding-bottom: 4px; /* 添加底部内边距，使符号向上移动 */
}

/* Markdown 内容样式 */
.thinking, .answer {
  pre {
    background-color: #f9fafb;
    border-radius: 4px;
    padding: 12px;
    margin: 12px 0;
  }
  
  code {
    font-family: 'Menlo', monospace;
    font-size: 13px;
    background-color: #f1f5f9;
    border-radius: 3px;
    padding: 2px 4px;
  }
  
  ul, ol {
    padding-left: 1.5em;
    margin: 0.5em 0;
  }
  
  a {
    color: #2563eb;
    text-decoration: none;
  }
  
  a:hover {
    text-decoration: underline;
  }
  
  blockquote {
    color: #666;
    border-left: 3px solid #ddd;
    margin: 0.5em 0;
    padding: 0.5em 1em;
  }
  
  h1, h2, h3, h4, h5, h6 {
    margin: 1em 0 0.5em;
    font-weight: 600;
    line-height: 1.3;
  }
}

/* 自定义滚动条样式 */
.github-theme::-webkit-scrollbar {
  width: 8px;
}

.github-theme::-webkit-scrollbar-track {
  background-color: transparent;
}

.github-theme::-webkit-scrollbar-thumb {
  background-color: #d1d5db;
  border-radius: 4px;
}

.github-theme::-webkit-scrollbar-thumb:hover {
  background-color: #9ca3af;
}

.messages::-webkit-scrollbar {
  width: 8px;
  position: absolute;
  right: 0;
}

.messages::-webkit-scrollbar-track {
  background-color: transparent;
}

.messages::-webkit-scrollbar-thumb {
  background-color: #d1d5db;
  border-radius: 4px;
}

.messages::-webkit-scrollbar-thumb:hover {
  background-color: #9ca3af;
}

/* 移动端适配 */
@media screen and (max-width: 768px) {
  .chat-container {
    max-width: 100%;
    padding: 0;
  }

  .header {
    padding: 12px;
    margin-bottom: 12px;
  }

  .header h1 {
    font-size: 20px;
  }

  .messages {
    padding: 12px;
    margin-bottom: 70px;
  }

  .message {
    margin: 12px 0;
  }

  .thinking, .answer, .user-msg {
    padding: 10px 12px;
    font-size: 14px;
  }

  .thinking blockquote {
    padding: 10px 12px;
  }

  /* 调整输入框区域 */
  .input-form {
    padding: 12px;
  }

  .input-container {
    gap: 6px;
  }

  input {
    padding: 8px 10px;
    font-size: 14px;
  }

  /* 调整按钮大小 */
  button {
    width: 56px;
    height: 34px;
    padding: 6px 12px;
    font-size: 14px;
  }

  /* 调整 AI 头像和用户头像大小 */
  .avatar {
    width: 28px;
    height: 28px;
    font-size: 12px;
  }

  /* 调整代码块显示 */
  .thinking pre, .answer pre {
    padding: 10px;
    font-size: 12px;
    overflow-x: auto;
  }

  code {
    font-size: 12px;
  }

  /* 调整链接和列表样式 */
  ul, ol {
    padding-left: 1.2em;
  }

  /* 调整移动端终止按钮样式 */
  button.cancel {
    font-size: 20px;  /* 减小终止符号大小 */
    padding-bottom:0;  /* 移除底部内边距 */
  }
}

/* 超小屏幕适配 */
@media screen and (max-width: 380px) {
  .header h1 {
    font-size: 18px;
  }

  .messages {
    padding: 8px;
  }

  .input-form {
    padding: 8px;
  }

  button {
    width: 50px;
    padding: 6px 8px;
  }

  button.cancel {
    font-size: 18px;  /* 在超小屏幕上进一步减小终止符号大小 */
    padding-bottom:0;  /* 移除底部内边距 */
  }
}
</style>


